#include "ui_handler.h"

UIHandler::UIHandler()
    : body_( 0 )
    , active_( 0 )
{
}

UIHandler::~UIHandler()
{
    if( body_ )
    {
        body_->Destroy();
        delete body_;
    }
}

void UIHandler::SetPath( const wchar_t *file )
{
    if( file )
        file_ = file;
}

BOOL UIHandler::Parse()
{
    if( file_.empty() )
    {
        return FALSE;
    }

    base::scoped_array<BYTE> byte_;
    WinResourceImpl * impl_ = WindowsFactory::Instance().GetResourceImpl();
    if( !impl_ )
    {
        return FALSE;
    }

    if( !impl_->GetBinaryResource( file_.c_str(), byte_.accept(), 0 ) )
    {
        return FALSE;
    }

    XmlDocument xmlDoc;
    if( !xmlDoc.Parse( (const char *)byte_.get() ) || xmlDoc.Error() )
    {
        return FALSE;
    }

    XmlElement * pRootElement = xmlDoc.RootElement();
    if( !pRootElement )
    {
        return FALSE;
    }

    const char * pszValue = pRootElement->Value();
    if( !pszValue || strcmp( pszValue, "xml" ) != 0 )
    {
        return FALSE;
    }

    XmlElement * pElementHead = pRootElement->FirstChildElement( "head" );
    if( !pElementHead )
    {
        return FALSE;
    }

    if( !ParseContext( pElementHead ) )
    {
        return FALSE;
    }

    XmlElement * pElementBody = pRootElement->FirstChildElement( "body" );
    if( !pElementBody )
    {
        return FALSE;
    }

    if( body_ )
    {
        body_->Destroy();
        delete body_;
    }

    body_ = new core::FaceWindow;
    if( body_ )
    {
        body_->SetName( "body" );
        core::uint lResult = body_->DispatchMessage( core::FM_LOAD, (core::uint)pElementBody, (core::uint)&style_manager_ );
        return lResult;
    }

    return FALSE;
}

core::FaceWindow * UIHandler::Generate( const char *xml )
{
    if( !xml )
    {
        return 0;
    }

    XmlDocument xmlDoc;
    xmlDoc.Parse( xml );
    if( xmlDoc.Error() )
    {
        return 0;
    }

    XmlElement * element = xmlDoc.RootElement();
    if( !element )
    {
        return 0;
    }

    const char * name = element->Value();
    core::FaceWindow * control = (core::FaceWindow *) RuntimeClass::CreateObject( name );

    if( control &&
        control->DispatchMessage( core::FM_LOAD, (core::uint)element, (core::uint)&style_manager_ ) )
    {
        return control;
    }

    if( control )
    {
        delete control;
    }

    return 0;
}

BOOL UIHandler::ParseContext( XmlElement * pElement )
{
    if( !pElement )
    {
        return FALSE;
    }

    XmlElement * pChild = pElement->FirstChildElement( "link" );
    while( pChild )
    {
        if( strcmp( pChild->Attribute( "type" ), "text/css" ) == 0 )
        {
            const char * file = pChild->Attribute( "href" );

            CString strFile = common::WinString::UTF8ToUnicode( file );
            base::scoped_array<BYTE> byte_;
            WinResourceImpl * impl_ = WindowsFactory::Instance().GetResourceImpl();
            if( !impl_ )
            {
                return FALSE;
            }
            if( impl_->GetBinaryResource( strFile, byte_.accept(), 0 ) )
            {
                style_manager_.Parse( (const char *)byte_.get() );
            }
        }

        pChild = pChild->NextSiblingElement( "link" );
    }

    return TRUE;
}

core::FaceWindow * UIHandler::Body()
{
    return body_;
}

core::FaceWindow * UIHandler::Active()
{
    return active_;
}

void UIHandler::SetActive( core::FaceWindow * control )
{
    active_ = control;
}

core::FaceStyleManager* UIHandler::StyleManager()
{
    return &style_manager_;
}

void UIHandler::SetWindowDelegate( core::HandleDelegate *delegate )
{
    if( body_ )
    {
        body_->SetHandleDelegate( delegate );
    }
}

core::FaceWindow * UIHandler::FindControl( const std::string &id )
{
    if( body_ )
    {
        return body_->FindChild( id, true );
    }

    return 0;
}